home *** CD-ROM | disk | FTP | other *** search
- /* +-----------------------------------+
- * | |
- * | CLASS.C |
- * | |
- * +-----------------------------------+
- *
- * James. P. Hawkins - WA2WHV
- * P.O. Box 9146,
- * Trenton, NJ 08650
- *
- * ALGEBRAIC EXPRESSION FIELD and OPERATOR CLASSIFIER
- * and SYNTAX CHECKER
- * (LEXICAL analyzer of sorts)
- *
- *
- * calling format:
- *
- * field class (or error) = class(&sptr, field);
- *
- * where the ADDRESS of the Pointer sptr MUST be passed
- * the input string pointer will be MODIFIED and
- * LEFT at a point after the field just parsed
- *
- * field = pointer to txtbuf where a null terminated copy
- * of the field just parsed will be left
- *
- * error code = negative of class
- * (i.e. a certain type field was attempted
- * but something illegal happened
- */
- #include "evalx.h"
- /*
- * the legdlm(X) check for legal delimeters or null (end of string)
- */
- #define cpychr() {*fptr++ = **sptr ; *sptr += 1; }
- #define legdlm(X) (any(X," ^*+/-)") || (X =='\0'))
-
- /* Skip white space macro */
- #define skipspace() {while(**sptr == ' ' || **sptr == '\t') *sptr +=1;}
-
- /* -------------------------------------------------------------------- */
- class(sptr, field)
- char **sptr; /* input string pointer */
- char *field; /* pointer to output field */
- {
- char *fptr; /* output field pointer */
- int pcnt; /* parenthesis best counter */
-
-
- pcnt = 0; /* init paren nest counter */
- fptr = field; /* init output field pointer */
- skipspace(); /* skip leading blanks and tabs */
-
- if(alpha(**sptr)) /* if 1st char is alpha */
- {
- cpychr(); /* copy first alpha */
- if(alpha(**sptr)) /* if second alpha it must be func */
- {
- /*
- * Copy until first non-alphanumeric
- * this must be a FUNCTION FIELD.
- * The first non-alpha numeric must be a '('
- */
- while(alpha(**sptr) || num(**sptr))
- {
- cpychr();
- }
-
- if(**sptr == '(') /* func name followed by '(' */
- {
- pcnt = 1; /* count first nest deep */
- cpychr(); /* copy initial '(' */
- /*
- * Scan stuff inside of parens.
- * parens must be balanced to terminate
- * function field.
- */
- while(pcnt > 0 && **sptr != 0)
- {
- switch(**sptr)
- {
- case '(':
- pcnt += 1;
- break;
- case ')':
- pcnt -= 1;
- break;
- default:
- break;
- }
- cpychr();
- }
-
- if(**sptr == 0 && pcnt != 0)
- {
- *fptr='\0';
- /*
- * line terminates before
- * function defined.
- */
- return(-FNCLASS);
- }
-
- if(legdlm(**sptr))
- {
- *fptr = '\0'; /* null term */
- /*
- * Return function class code
- */
- return(FNCLASS);
- }
- else /* illegal delim */
- {
- return(-FNCLASS);
- }
- }
- else
- {
- return(-FNCLASS); /* function def without
- '(' */
- }
- }
- else /* VARIABLE OR VARIABLE ARRAY FIELD */
- {
- if(num(**sptr))
- {
- cpychr(); /* cpy numeric part of var name */
- }
-
- if(**sptr == '(') /* array paren? */
- {
- pcnt = 1; /* init paren count */
- cpychr(); /* copy 1st paren */
- /*
- * scan stuff inside of parens.
- * parens must be balanced to terminate
- * function field.
- */
- while(pcnt > 0 && **sptr != 0)
- {
- switch(**sptr)
- {
- case '(':
- pcnt += 1;
- break;
- case ')':
- pcnt -= 1;
- break;
- default:
- break;
- }
- cpychr();
- }
-
- if(**sptr == 0 && pcnt != 0)
- {
- *fptr='\0';
- /*
- * line terminates before array
- * defined
- */
- return(-VACLASS);
- }
- if(legdlm(**sptr))
- {
- *fptr = '\0'; /* null term */
- return(VACLASS);
- }
- else
- {
- *fptr = '\0';
- /* ill delim */
- return(-VACLASS);
- }
- }
- else /* VARIABLE NAME FIELD */
- {
- if(legdlm(**sptr)) /* legal delimiter */
- {
- *fptr = '\0'; /* null term */
- return(VRCLASS);
- }
- else
- {
- return(-VRCLASS); /* ill delim */
- }
- }
- }
- }
- else /* EITHER NUMERIC OR OPERATOR FIELD */
- {
- if(num(**sptr) || **sptr == '.')
- {
- cpychr(); /* copy 1st dig of num */
-
- while(num(**sptr)) /* copy all consec dig */
- {
- cpychr();
- }
-
- if(**sptr == '.') /* embedded '.' is allowed */
- {
- cpychr(); /* copy '.' */
- while(num(**sptr)) /* get digits following
- decimal point */
- {
- cpychr();
- }
- }
- if(**sptr == 'e' || **sptr == 'E')
- {
- cpychr();
- /*
- * HANDLE EXPONENTIAL NOTATION TYPE
- */
- if(**sptr == '+' || **sptr == '-')
- {
- cpychr();
- if(num(**sptr))
- {
- /* copy exponent */
- while(num(**sptr))
- {
- cpychr();
- }
- }
- else
- {
- return(-NMCLASS);
- }
- }
- else
- {
- return(-NMCLASS);
- }
- }
- if(legdlm(**sptr)) /* check for legal delim */
- {
- *fptr = '\0'; /* null term */
- return(NMCLASS); /* numeric */
- }
- else
- {
- return(-NMCLASS); /* ill delim */
- }
- }
- else /* OPERATOR FIELD */
- {
- if(any(**sptr, "^*/+-()"))
- {
- cpychr(); /* copy the operator */
- *fptr = '\0'; /* term with null */
- return(OPCLASS); /* operator */
- }
- else
- {
- return(-OPCLASS); /* illegal delim */
- }
- }
- }
- }
-
- /* ------------------------------------------------------------------- */
- /*
- *
- * //////// TRUE IF ANY CHARS IN STRING as MATCH c ////////
- */
- any(c, as)
- int c;
- char *as;
- {
- register char *s;
-
- s = as;
- while(*s)
- {
- if(*s++ == c)
- {
- return(1);
- }
- }
- return(0);
- }
-
-
- /* ------------------------------------------------------------------- */
- /*
- * //// TRUE IF NUMERIC ////
- */
- num(c)
- char c;
- {
- if(c >= '0' && c <= '9')
- {
- return(1);
- }
- else
- {
- return(0);
- }
- }
-
- /* ------------------------------------------------------------------- */
- /*
- * //// TRUE IF ALPHA lower case ////
- */
- alpha(c)
- char c;
- {
- if(c >= 'a' && c <= 'z')
- {
- return(1);
- }
- else
- {
- return(0);
- }
- }
-